from model.note_model import *
import time,glob

import sys, yaml

sys.path.append('..')

import config.config as config


markups = {'markdown': '_', 'textile': '__'}


class NoteController(object):
	"""The Note class."""
	def __init__(self, db=None):
		if db:
			self.note = NoteModel(db)
		else:
			self.note = NoteModel()
				
	def search(self, keywords = ''):
		# parse line
		keywords = self.parse_command(keywords)['search']
		notes = self.note.query(keywords)
		
		trashed_symbol = '%s%s' % (config.trashed_header, config.sep)
		soft_trashed = keywords.find(trashed_symbol) >= 0
		if soft_trashed:
			return [note for note in notes if note['content'].startswith(trashed_symbol) ]
		else:
			return [note for note in notes if not note['content'].startswith(trashed_symbol)]

	def search_header(self, keywords):
		notes = self.search()
		
		found = []
		for note in notes:
			if self.get_header(note).find( keywords ) >= 0:
				found.append( note )
		
		return found
			
	def parse_command(self, line):
		commands = {
			'export'	:	{'args'		:	['search', 'path'] }, 
			'impoft'	:	{'args'		:	['path',] }
			}
		
		parsed = { 'command' : '', 'search' : '', 'args' : ''}
		line = line.strip()
		if not line.startswith('!'):
			parsed['search'] = line
			return parsed
		else:
			line = line[1:]
			
			if not line:
				return parsed

			tokens = line.split('!')
			
			if len(tokens) > 1:
				command_and_search = tokens[0]
				parsed['args'] = tokens[1].strip()
			else:
				command_and_search = tokens[0]
			
			if not command_and_search:
				return parsed
			
			tokens = command_and_search.split()
			
			if not tokens:
				return parsed
				
			if len(tokens) == 1:
				parsed['command'] = tokens[0]
				return parsed
			else:
				parsed['command'] = tokens[0]
				parsed['search'] = tokens[1]
				return parsed
		
				
				
				

	def run_command(self, keywords):
		keywords = keywords.strip()
		
		parsed = self.parse_command(keywords)
		
		command = parsed['command']
		args = parsed['args']
		search = parsed['search']

		
		if command == 'export':
			path = args
			if path:
				notes = self.search(keywords)
				if notes:
					if not path.endswith('.yaml'):
						path += '.yaml'
					self.export_notes( notes, path )
					return True
	
		elif command == 'import':
			path = args
			if path:
				if not os.path.exists(path):
					if not path.endswith('.yaml'):
						path += '.yaml'
						if not os.path.exists(path):
							return
				self.import_notes(path)
				return True
				
		
	def soft_trash(self, note):
		trashed_symbol = '%s%s' % (config.trashed_header, config.sep)
		if note['content'].startswith(trashed_symbol):
			content = note['content'][len(trashed_symbol):]
		else:
			content = '%s%s%s' % (config.trashed_header, config.sep, note['content'] )
		note['content'] = content
		return self.edit(note)
	
	def hard_trash(self, note):
		trashed_symbol = '%s%s' % (config.trashed_header, config.sep)
		if note['content'].startswith(trashed_symbol):
			return self.remove(note)
			
	def add(self, content):
		return self.note.add(content)
	
	def edit(self, note):
		return self.note.edit(note['id'], note['content'])
		
	def remove(self, note):
		return self.note.remove(note['id'])
		
	def history(self, note, revision=-1):
		return self.note.history(note['id'], revision)
		
	def rollback(self, note, revision):
		return self.note.rollback(note['id'], revision)
		
	def dummy(self):
		return {'revision': 0, 'content' : u'', 'timestamp' : int(time.time()), 'last_revision':0}
		
	def get_header(self, note):
		return note['content'].lstrip().split('\n')[0]
		
	def get_smart_header(self, note):
		header = self.get_header(note)
		keys = header.split(config.sep)

		mark = keys[-1]
		header_dict = {}
		
		if set([mark]).intersection(markups.keys()):
			header_dict['markup'] = config.sep + markups[mark]
			header_dict['header'] = '.'.join(keys[:-1])
		else:
			header_dict['header'] = header
			header_dict['markup'] = ''
		
		if note['revision'] != note['last_revision']:
			header_dict['revision'] = '%s/%s%s' % ( note['revision'], note['last_revision'], config.sep)
		else:
			header_dict['revision'] = ''
		header_dict['full'] = header
		return header_dict
	
	def get_body(self, note):
		return '\n'.join(note['content'].lstrip().split('\n')[1:])
		
	def get_markup(self, note):
		
		header = self.get_header(note)
		if header:
			markup = header.split(config.sep)[-1]
			if markup in markups.keys():
				return markup
				
	def import_notes(self, path):
		if os.path.exists(path):
			notes = None
			try:
				f = open(path)
				notes = yaml.load(f)
				f.close()
			except Exception, e:
				print e
			
			if notes:
				for note in notes:
					self.add(note['content'])

	def export_notes(self, notes, path=None):
		if path:
			try:
				f = open( path, 'w')
				f.write(yaml.dump(notes, default_flow_style=False))
				f.close()
			except Exception, e:
				print e
